package webx;

import stdx.Utils;
import dbx.DBConnect;
import dbx.RedisConnect;
import java.util.ArrayList;
import webx.http.HttpRequest;
import webx.http.HttpResponse;

public class Startup extends WebApp{
	public static class DBConfig{
		public int port;
		public String id;
		public String host;
		public String type;
		public String name;
		public String user;
		public String charset;
		public String password;
	}

	private static int dbconnmaxlen = 8;
	private static int dbconntimeout = 60;

	@SuppressWarnings("unchecked")
	public byte[] getCgiPath(byte[] path){
		try{
			String tmp = new String(path);

			tmp = tmp.replace('/', '.');
			tmp = tmp.replace('\\', '.');

			Class clazz = Class.forName(tmp);
			Path cgipath = (Path)clazz.getAnnotation(Path.class);

			if (cgipath == null) return null;

			Document document = (Document)clazz.getAnnotation(Document.class);
			TimerTask timertask = (TimerTask)clazz.getAnnotation(TimerTask.class);
			DailyTask dailytask = (DailyTask)clazz.getAnnotation(DailyTask.class);

			tmp = GetWebAppPath(cgipath.value(), new String(path));
			SetCgiDefaultGroup(tmp, cgipath.group());
			SetCgiAccess(tmp, cgipath.access());

			if (document != null){
				SetCgiDoc(tmp, GetDocString(document.request()), GetDocString(document.response()), document.remark());
			}

			if (timertask != null){
				SetCgiExtdata(tmp, "timertask=" + timertask.value());
				SetCgiAccess(tmp, "protect");
			}

			if (dailytask != null){
				SetCgiExtdata(tmp, "dailytask=" + dailytask.value());
				SetCgiAccess(tmp, "protect");
			}

			return tmp.getBytes();
		}
		catch (Exception e){
			e.printStackTrace();
		}

		return null;
	}

	public void process(HttpRequest request, HttpResponse response) throws Exception{
		System.load(WebApp.GetPluginPath() + "/InitSystem.so");

		int port = 0;
		String path = request.get("path");
		String host = WebApp.GetConfig("redis.host");
		String password = WebApp.GetConfig("redis.password");

		if (Utils.IsNotEmpty(host)){
			try {
				port = Integer.parseInt(WebApp.GetConfig("redis.port"));

				RedisConnect.GetPool().init(host, port, password, false).get();

				LogFile.Trace(LogFile.IMP, "initialize redis[%s:%d] success", host, port);
			}
			catch(Exception e){
				LogFile.Trace(LogFile.ERR, "initialize redis[%s:%d] failed", host, port);
			}
		}

		int dbconnmaxlen = 8;
		int dbconntimeout = 60;
		String type = WebApp.GetConfig("database.type");
		String user = WebApp.GetConfig("database.user");
		String name = WebApp.GetConfig("database.name");
		String charset = WebApp.GetConfig("database.charset");

		host = WebApp.GetConfig("database.host");
		password = WebApp.GetConfig("database.password");

		try {
			port = Integer.parseInt(WebApp.GetConfig("database.port"));
		}
		catch (Exception e){
		}

		try {
			dbconnmaxlen = Integer.parseInt(WebApp.GetConfig("database.maxsize"));
		}
		catch (Exception e){
		}

		try {
			dbconntimeout = Integer.parseInt(WebApp.GetConfig("database.timeout"));
		}
		catch (Exception e){
		}

		if (Utils.IsNotEmpty(name) && initdb(null, type, host, port, name, user, password, charset)){
			DBConnect dbconn = DBConnect.Connect();

			try{
				String sql = "SELECT ID,TYPE,HOST,PORT,NAME,USER,PASSWORD,CHARSET FROM T_XG_DBETC WHERE ENABLED>0";

				ArrayList<DBConfig> vec = dbconn.selectList(DBConfig.class, sql);

				for (DBConfig item : vec) initdb(item.id, item.type, item.host, item.port, item.name, item.user, item.password, item.charset);
			}
			catch(Exception e){
				e.printStackTrace();
			}
			finally{
				Utils.Close(dbconn);
			}
		}
	}
	public boolean initdb(String dbid, String type, String host, int port, String name, String user, String password, String charset){
		DBConnect.Config db = new DBConnect.Config();

		db.user = user;
		db.password = password;

		name = Utils.Translate(name);

		if (Utils.IsEmpty(type)){
			type = "sqlite";
		}
		else{
			type = type.toLowerCase();
		}

		if (Utils.IsEmpty(charset)){
			charset = "utf-8";
		}

		if (type.indexOf("mysql") >= 0){
			db.url = String.format("jdbc:mysql://%s:%d/%s?useUnicode=true&characterEncoding=%s", host, port, name, charset);
		}
		else if (type.indexOf("oracle") >= 0){
			db.url = String.format("jdbc:oracle:thin:@%s:%d/%s", host, port, name);
		}
		else if (type.indexOf("postgres") >= 0){
			db.url = String.format("jdbc:postgresql://%s:%d/%s", host, port, name);
		}
		else{
			db.url = String.format("jdbc:sqlite:%s", name);
		}

		if (Utils.IsEmpty(db.url)) return false;

		try{
			DBConnect dbconn = null;

			if (dbid == null){
				dbconn = DBConnect.GetPool().init(db, dbconnmaxlen, dbconntimeout).get();
			}
			else{
				dbconn = DBConnect.GetPool(dbid).init(db, dbconnmaxlen, dbconntimeout).get();
			}

			LogFile.Trace(LogFile.IMP, "initialize database[%s] success", db.url);

			Utils.Close(dbconn);

			return true;
		}
		catch(Exception e){
			LogFile.Trace(LogFile.ERR, "initialize database[%s] failed[%s]", db.url, e.getMessage());

			e.printStackTrace();

			return false;
		}
	}
}